# 导入需要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# 设置中文字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "Arial Unicode MS"]
plt.rcParams['axes.unicode_minus'] = False

# 加载数据并选择特征
iris = load_iris()
X = iris.data[:, [2, 3]]  # 选择花瓣长度(第3列)和花瓣宽度(第4列)作为特征
y = iris.target  # 标签(0,1,2分别代表三种鸢尾花)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)  # 测试集占30%，随机种子保证结果可复现

# 训练逻辑回归模型
lr = LogisticRegression(max_iter=1000)  # 初始化模型，增加迭代次数确保收敛
lr.fit(X_train, y_train)  # 用训练集训练模型

# 评估模型
y_pred = lr.predict(X_test)  # 用测试集预测
accuracy = accuracy_score(y_test, y_pred)  # 计算准确率
print(f"模型准确率: {accuracy:.2f}")  # 输出准确率(保留两位小数)

# 可视化分类结果
# 生成网格点用于绘制决策边界
h = 0.02  # 网格步长
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1  # 花瓣长度范围
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1  # 花瓣宽度范围
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),np.arange(y_min, y_max, h))  # 生成网格

# 预测网格点的类别
Z = lr.predict(np.c_[xx.ravel(), yy.ravel()])  # ravel()将二维转为一维，c_按列拼接
Z = Z.reshape(xx.shape)  # 转换为与网格相同的形状

# 绘制分类区域和样本点
plt.figure(figsize=(8, 6))  # 设置图的大小
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.Paired)  # 绘制分类区域(填充颜色)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', cmap=plt.cm.Paired)  # 绘制样本点
plt.xlabel('花瓣长度')  # x轴标签
plt.ylabel('花瓣宽度')  # y轴标签
plt.title('鸢尾花逻辑回归分类结果')  # 图标题
plt.show()  # 显示图像